package state;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

import state.util.SerialUtil;

public class ResourceRms {
  private static Hashtable recordStoreMap = new Hashtable();
  
	private static final String MASTER_SUFFIX = "master";
	private static final String RESOURCE_SUFFIX = "resource";
	
	public static Hashtable loadMasterRecord(String category) {
		Hashtable hashtable = new Hashtable();
		RecordStore masterRecordStore = null;
		try {
			masterRecordStore = RecordStore.openRecordStore(category + MASTER_SUFFIX, false);
			if ((masterRecordStore == null) || (masterRecordStore.getNumRecords() == 0)) {
			  return null;
			}
			
			byte[] data = masterRecordStore.getRecord(1);
			int index = 0;
			while(index < data.length - 1) {
				int len = SerialUtil.getInt(data, index);
				index += 4;
				String key = SerialUtil.getString(data, index, len);
				index += len;
				int value = SerialUtil.getInt(data, index);
				index += 4;
				hashtable.put(key, new Integer(value));
			}
			return hashtable;
		} catch (Exception e) {
			return null;
		} finally {
			if (masterRecordStore != null) {
				try {
					masterRecordStore.closeRecordStore();
				} catch (RecordStoreNotOpenException e) {
				} catch (RecordStoreException e) {
				}
			}
		}
	}
	
	public static void saveMasterRecord(String category, Hashtable hashtable) {
		int len = 0;
		Enumeration e = hashtable.keys();
		while (e.hasMoreElements()) {
			String key = String.valueOf(e.nextElement());
			len += (4 + key.getBytes().length);
			len += 4; //4 byte dành cho value
		}
		
		byte[] data = new byte[len];
		e = hashtable.keys();
		int index = 0;
		while (e.hasMoreElements()) {
			String key = String.valueOf(e.nextElement());
			byte[] bytes = key.getBytes();
			System.arraycopy(SerialUtil.serialNumber(bytes.length), 0, data, index, 4);
			index += 4;
			System.arraycopy(bytes, 0, data, index, bytes.length);
			index += bytes.length;
			int value = ((Integer) hashtable.get(key)).intValue();
			System.arraycopy(SerialUtil.serialNumber(value), 0, data, index, 4);
			index += 4;
		}
		
		RecordStore masterRecordStore = null;
		
		try {
      RecordStore.deleteRecordStore(category + MASTER_SUFFIX);
    } catch (Exception e1) {
    }
		
		try {
			masterRecordStore = RecordStore.openRecordStore(category + MASTER_SUFFIX, true);
			masterRecordStore.addRecord(data, 0, data.length);
		} catch (Exception e1) {
		} finally {
			if (masterRecordStore != null) {
				try {
					masterRecordStore.closeRecordStore();
				} catch (RecordStoreNotOpenException e1) {
				} catch (RecordStoreException e1) {
				}
			}
		}
	}

	public static Image getImage(String category, int recordIndex) {
	  ByteArrayInputStream byteArrayInputStream = null;
		try {
		  RecordStore recordStore = getConnectionResource(category);
			if (recordStore.getNumRecords() < recordIndex) {
				return null;
			}
			byteArrayInputStream = new ByteArrayInputStream(recordStore.getRecord(recordIndex));
			return Image.createImage(byteArrayInputStream);
		} catch (Exception e) {
			return null;
		} finally {
		  try {
		    if (byteArrayInputStream != null) {
		      byteArrayInputStream.close();
		    }
      } catch (IOException e) {
      }
		}
	}
	
	public static byte[] getResourceAsByteArray(String category, int recordIndex) {
	  try {
      RecordStore recordStore = getConnectionResource(category);
      if (recordStore.getNumRecords() < recordIndex) {
        return null;
      }
      return recordStore.getRecord(recordIndex);
    } catch (Exception e) {
      return null;
    }
	}

	public static int saveImageData(String category, byte[] data) {
		try {
			return getConnectionResource(category).addRecord(data, 0, data.length);
		} catch (Exception e) {
			return -1;
		}
	}
	
	private static RecordStore getConnectionResource(String category) throws Exception {
	  RecordStore recordStore = (RecordStore) recordStoreMap.get(category);
    if (recordStore == null) {
      recordStore = RecordStore.openRecordStore(category + RESOURCE_SUFFIX, true);
      recordStoreMap.put(category, recordStore);
    }
    return recordStore;
	}
	
	public static void close(String category) {
		try {
		  RecordStore recordStore = (RecordStore) recordStoreMap.get(category);
			if (recordStore != null) {
			  recordStore.closeRecordStore();
			  recordStoreMap.remove(category);
			}
		} catch (RecordStoreNotOpenException e) {
		} catch (RecordStoreException e) {
		}
	}
	
	public static void closeAll() {
	  Enumeration categories = recordStoreMap.keys();
	  while(categories.hasMoreElements()) {
	    String category = String.valueOf(categories.nextElement());
	    close(category);
	  }
	}
}
